import { asyncRoutes, constantRoutes } from '@/router'
import { isAnyGranted } from '@/utils/auth/permission-checker'
import { getToken, setToken, clearToken } from '@/utils/auth/token'
import { setCookieValue } from '@/utils/utils'
// import { appConsts } from '@/utils/app-consts'
import { login } from '@/api/account'
import dayjs from 'dayjs'
import abp from 'abp'

const state = {
  token: getToken(),
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  // add token
  addToken({ commit }, user) {
    return new Promise((resolve, reject) => {
      const { access_token, expires_at } = user
      const tokenExpireDate = expires_at ? dayjs(expires_at * 1000).toDate() : undefined
      commit('SET_TOKEN', access_token)
      setToken(access_token, tokenExpireDate)
      // setCookieValue(appConsts.authorization.encrptedAuthTokenName, encryptedAccessToken, tokenExpireDate, abp.appPath)      
      resolve()
    })
  },
  accessToken({ commit }, loginData) {
    const { rememberMe, username, password } = loginData
    return new Promise((resolve, reject) => {
      // var loginData = {
      //   grant_type: 'password',
      //   client_id: process.env.VUE_APP_OAUTH_CLIENT_ID,
      //   client_secret: process.env.VUE_APP_OAUTH_CLIENT_SECRET,
      //   username: username.trim(),
      //   password: password
      // }
      const tokenExpireDate = rememberMe ? (new Date(new Date().getTime() + 1000 * 36000)) : undefined
      commit('SET_TOKEN', 'staticTOKEN')
      setToken('staticTOKEN', tokenExpireDate)
      setCookieValue('refresh_token', 'staticTOKEN', (new Date(new Date().getTime() + 10 * 365 * 24 * 60 * 60 * 1000)), abp.appPath)
      resolve()
      // login(loginData).then(data => {
      //   const { access_token, refresh_token, expires_in } = data
      //   const tokenExpireDate = rememberMe ? (new Date(new Date().getTime() + 1000 * expires_in)) : undefined
      //   commit('SET_TOKEN', access_token)
      //   setToken(access_token, tokenExpireDate)
      //   setCookieValue('refresh_token', refresh_token, (new Date(new Date().getTime() + 10 * 365 * 24 * 60 * 60 * 1000)), abp.appPath)
      //   resolve()
      // }).catch(error => {
      //   reject(error)
      // })
    })
  },
  // remove token
  removeToken({ commit }) {
    return new Promise(resolve => {
      commit('SET_TOKEN', '')
      clearToken()
      resolve()
    })
  },
  generateRoutes({ commit }) {
    return new Promise(resolve => {
      const accessedRoutes = filterAsyncRoutes(asyncRoutes)
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 */
export function filterAsyncRoutes(routes) {
  const res = []

  routes.forEach(route => {
    if (route.name === 'demo' && process.env.NODE_ENV !== 'development') {
      return;
    }

    const tmp = { ...route }
    if (hasPermissions(tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children)
      }
      res.push(tmp)
    }
  })

  return res
}

/**
 * Use meta.role to determine if the current user has permission
 * @param route
 */
function hasPermissions(route) {
  if (route.meta && route.meta.permissions) {
    return isAnyGranted(route.meta.permissions)
  } else {
    return true
  }
}
